﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Serialization;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Markup;

namespace BCL.Tool
{
    /// <summary>
    /// 语言包
    /// </summary>
    public static class LanguagePackage
    {
        private static LanguageConfig config;
        private static string defaultLanguage = "zh-cn";
        private static string languagePath = AppDomain.CurrentDomain.BaseDirectory + "language\\";

        public static Dictionary<string, string> LangContent;
        public static string Language(this string key)
        {
            if (string.IsNullOrEmpty(key))
                return "";
            if (LangContent != null)
            {
                string value = key;
                if (LangContent.TryGetValue(key, out value))
                    return string.IsNullOrEmpty(value) ? key : value;
                LangContent.Add(key, key);
                config.AddKey(key);
            }
            return key;
        }

        public static bool SetLanguage(LanguageKeyValue obj)
        {
            LanguageKeyValue lkv = obj as LanguageKeyValue;
            if (lkv != null)
            {
                config.SetLanguage(lkv.Key);
                if (config.Default == defaultLanguage)
                    LangContent = null;
                else
                    LangContent = config.LoadLanguageForXml();
                return true;
            }
            return false;
        }

        public static List<LanguageKeyValue> GetLanguagePackages()
        {
            if (config != null)
                return config.LanguagePackages;
            return null;
            //if (config.LanguagePackages == null)
            //    return null;
            //return config.LanguagePackages;
        }

        static LanguagePackage()
        {
            try
            {
                if (!Directory.Exists(languagePath))
                    Directory.CreateDirectory(languagePath);
                config = new LanguageConfig(languagePath);
                if (config.Default != defaultLanguage)
                    LangContent = config.LoadLanguageForXml();
            }
            catch (Exception)
            {
            }

        }
    }

    [Serializable]
    public class LanguageConfig
    {
        private List<LanguageKeyValue> list;
        private string configPath = "";
        private string basePath = "";
        private string xmlPath = "";
        public string Default
        {
            get;
            set;
        }

        public string LanguageXmlPath
        {
            get;
            set;
        }

        public List<LanguageKeyValue> LanguagePackages
        {
            get;
            set;
        }


        public void AddKey(string key)
        {
            if (list == null)
                list = new List<LanguageKeyValue>();
            list.Add(new LanguageKeyValue { Key = key, Value = " " });
            using (FileStream fs = File.Create(xmlPath))
            {
                XmlSerializer xml = new XmlSerializer(typeof(List<LanguageKeyValue>));
                xml.Serialize(fs, list);
            }
        }
        public Dictionary<string, string> LoadLanguageForXml()
        {
            Dictionary<string, string> lgs = new Dictionary<string, string>();
            if (!File.Exists(xmlPath))
            {
                list = new List<LanguageKeyValue>();
                list.Add(new LanguageKeyValue { Key = "视图", Value = "视图" });
                using (FileStream fs = File.Create(xmlPath))
                {
                    XmlSerializer xml = new XmlSerializer(typeof(List<LanguageKeyValue>));
                    xml.Serialize(fs, list);
                }
            }
            else
            {
                using (FileStream fs = File.OpenRead(xmlPath))
                {
                    XmlSerializer xml = new XmlSerializer(typeof(List<LanguageKeyValue>));
                    list = (List<LanguageKeyValue>)xml.Deserialize(fs);
                }
            }
            if (list == null)
                return null;
            Dictionary<string, string> da = new Dictionary<string, string>();
            foreach (var item in list)
                da.Add(item.Key, item.Value);
            return da;
        }


        public LanguageConfig()
        {

        }
        public LanguageConfig(string languagePath)
        {
            configPath = languagePath + "config.xml";
            basePath = languagePath;
            FillConfig(languagePath);
            xmlPath = basePath + LanguageXmlPath;
        }

        private void FillConfig(string languagePath)
        {
            if (!Directory.Exists(languagePath))
                Directory.CreateDirectory(languagePath);
            if (!File.Exists(configPath))
            {
                LanguagePackages = new List<LanguageKeyValue>();
                LanguagePackages.Add(new LanguageKeyValue { Key = "zh-cn", Value = "简体中文" });
                LanguagePackages.Add(new LanguageKeyValue { Key = "zh-tw", Value = "繁體中文" });
                LanguagePackages.Add(new LanguageKeyValue { Key = "en", Value = "English" });
                LanguagePackages.Add(new LanguageKeyValue { Key = "ja", Value = "日本語" });
                LanguagePackages.Add(new LanguageKeyValue { Key = "re", Value = "俄语" });
                LanguagePackages.Add(new LanguageKeyValue { Key = "ko", Value = "朝鲜语" });
                Default = "zh-cn";
                using (FileStream fs = File.Create(configPath))
                {
                    XmlSerializer xml = new XmlSerializer(typeof(LanguageConfig));
                    xml.Serialize(fs, this);
                }
            }
            else
            {
                using (FileStream fs = File.OpenRead(configPath))
                {
                    XmlSerializer xml = new XmlSerializer(typeof(LanguageConfig));
                    LanguageConfig config = (LanguageConfig)xml.Deserialize(fs);
                    if (config != null)
                    {
                        LanguagePackages = config.LanguagePackages;
                        Default = config.Default;
                        LanguageXmlPath = config.LanguageXmlPath;
                    }
                }
            }

        }

        public bool SetLanguage(string lname)
        {
            if (Default == lname)
                return false;
            if (LanguagePackages != null)
            {
                foreach (var item in LanguagePackages)
                {
                    if (item.Key == lname)
                    {
                        Default = item.Key;
                        LanguageXmlPath = item.Key + ".xml";
                        xmlPath = basePath + LanguageXmlPath;
                        using (FileStream fs = File.Create(configPath))
                        {
                            XmlSerializer xml = new XmlSerializer(typeof(LanguageConfig));
                            xml.Serialize(fs, this);
                        }
                        break;
                    }
                }
            }
            return true;
        }
    }

    [Serializable]
    public class LanguageKeyValue
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }


    public class LanguageValueConverter : MarkupExtension, IValueConverter
    {
        private static LanguageValueConverter lvc = new LanguageValueConverter();
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
                return value.ToString().Language();

            if (parameter != null)
                return parameter.ToString().Language();
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return lvc;
        }
    }
}
